﻿#include "FITKAbaqusAdaptorSpringDashpot.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaTransform.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSpringDashpotPoint2Point.h"
#include <QDebug>
//命名空间
namespace IO
{
    QString FITKAbaqusAdaptorSpringDashpot::getAdaptorClass()
    {
        return "IO::FITKAbaqusAdaptorSpringDashpot";
    }

    void FITKAbaqusAdaptorSpringDashpot::setModelDataCaseData(Interface::FITKAbstractModel* modelData, AbaqusData::FITKDataCase* caseData)
    {
        _modelData = modelData;
        _caseData = caseData;
    }

    void FITKAbaqusAdaptorSpringDashpot::setWriteElementId(int* writeElementId)
    {
        _writeElementId = writeElementId;
    }

    bool FITKAbaqusAdaptorSpringDashpot::adaptR()
    {
        //获取数据
        Interface::FITKAbaAbstractSpringDashpot* springDashpot = dynamic_cast<Interface::FITKAbaAbstractSpringDashpot*>(_dataObj);
        if (!springDashpot || !_reader)return false;
        bool readOK = false;
        //获取类型
        Interface::FITKAbaAbstractSpringDashpot::SpringDashpotType type = springDashpot->getSpringDashpotType();
        if (type == Interface::FITKAbaAbstractSpringDashpot::SpringDashpotType::ConnectTwoPoints)
            readOK = this->readConnectTwoPoints();
        return readOK;
    }

    bool FITKAbaqusAdaptorSpringDashpot::adaptW()
    {
        //写出
        Interface::FITKAbaAbstractSpringDashpot* springDashpot = dynamic_cast<Interface::FITKAbaAbstractSpringDashpot*>(_dataObj);
        if (!springDashpot || !_writer)return false;
        bool writerOK = false;
        //获取类型
        Interface::FITKAbaAbstractSpringDashpot::SpringDashpotType type = springDashpot->getSpringDashpotType();
        if (type == Interface::FITKAbaAbstractSpringDashpot::SpringDashpotType::ConnectTwoPoints)
            writerOK = this->writeConnectTwoPoints();
        return  writerOK;
    }

    bool FITKAbaqusAdaptorSpringDashpot::readConnectTwoPoints()
    {
        Interface::FITKAbaSpringDashpotPoint2Point* point2 = dynamic_cast<Interface::FITKAbaSpringDashpotPoint2Point*>(_dataObj);
        if (!point2 || !_reader)return false;
        //后退一行读取数据
        _reader->backLine();
        QString line = _reader->readLine();
        InpKeyLineSpliter s(line, _reader);
        //获取名称
        QString sH = s.getHeader().toLower();
        QString elset = s["elset"];
        point2->setDataObjectName(elset);
        //读取和设置坐标系
        if (s.hasKey("orientation"))
            if (!readOrientation("Ori_" + s["orientation"].trimmed()))
                return false;
        QString line1 = _reader->readLine().trimmed();
        if (line1.startsWith("*"))return false;
        QString line2 = _reader->readLine();
        if (line2.startsWith("*"))return false;
        //初始化
        point2->setStiffnessState(false);
        point2->setDaspotState(false);
        bool ok = false;
        if (line1.isEmpty())
        {
            //轴类型：跟随行动线
        }
        else
        {
            //轴类型：指定固定方向
        }
        //读取弹簧刚度/阻尼系数
        QStringList str = line2.split(',');
        if (str.size() < 1)return false;
        double v = str.at(0).toDouble(&ok);
        if (!ok)return false;
        if (sH == "spring")
        {
            point2->setStiffnessState(true);
            point2->setSpringStiffness(v);
        }
        else if (sH == "dashpot")
        {
            point2->setDaspotState(true);
            point2->setDaspotCoefficent(v);
        }
        _reader->readLine();
        return true;
    }

    bool FITKAbaqusAdaptorSpringDashpot::writeConnectTwoPoints()
    {
        Interface::FITKAbaSpringDashpotPoint2Point* point2 = dynamic_cast<Interface::FITKAbaSpringDashpotPoint2Point*>(_dataObj);
        if (!point2 || !_writer)return false;
        QTextStream* stream = _writer->getStream();
        QString name = point2->getDataObjectName();
        //获取指定方向
        QString direction = "";
        if (point2->getStiffnessState())
        {
            QString springName = QString("%1-spring").arg(name);
            springName = springName.contains(' ') ? QString("\"%1\"").arg(springName) : springName;
            QString lineOne = QString("*Spring, elset=%1").arg(springName);
            *stream << lineOne << endl;
            //写出指定方向
            *stream << direction << endl;
            //写出数据
            *stream << _writer->double2String(point2->getSpringStiffness(), 9, 0) << endl;
        }
        if (point2->getDaspotState())
        {
            QString dashpotName = QString("%1-dashpot").arg(name);
            dashpotName = dashpotName.contains(' ') ? QString("\"%1\"").arg(dashpotName) : dashpotName;
            QString lineOne = QString("*Dashpot, elset=%1").arg(dashpotName);
            *stream << lineOne << endl;
            //写出指定方向
            *stream << direction << endl;
            //写出数据
            *stream << _writer->double2String(point2->getDaspotCoefficent(), 9, 0) << endl;
        }

        //写出element
        if (!this->writeElementTwoPoints())return false;
        return true;
    }

    bool FITKAbaqusAdaptorSpringDashpot::readOrientation(QString ori)
    {
        if (!_modelData || !_dataObj)return false;
        if (_modelData->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AMTMIX)
        {
            //partData
            AbaqusData::FITKAbaqusPart* partData = dynamic_cast<AbaqusData::FITKAbaqusPart*>(_modelData);
            if (!partData)return false;
            //获取局部坐标系管理器
            Interface::FITKCoordinateSystemManager* sysManager = partData->getCoordinateSystemManager();
            if (!sysManager)return false;
            //获取局部坐标系
            Interface::FITKCoordinateSystem* csysData = sysManager->getDataByName(ori);
            if (!csysData)return false;
            //获取数据
            Interface::FITKAbaAbstractSpringDashpot* springDashpot = dynamic_cast<Interface::FITKAbaAbstractSpringDashpot*>(_dataObj);
            if (!springDashpot)return false;
            //设置局部坐标系
        }
        else if (_modelData->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::Assembly)
        {
            //assemblyData
            Interface::FITKAbaAssembly* assemblyData = dynamic_cast<Interface::FITKAbaAssembly*>(_modelData);
            if (!assemblyData)return false;
            //获取局部坐标系管理器
            Interface::FITKAbaTransformManager* sysManager = assemblyData->getTransformManager();
            if (!sysManager)return false;
            //获取局部坐标系
            Interface::FITKAbaTransform* csysData = sysManager->getDataByName(ori);
            if (!csysData)return false;
            // 获取数据
            Interface::FITKAbaAbstractSpringDashpot* springDashpot = dynamic_cast<Interface::FITKAbaAbstractSpringDashpot*>(_dataObj);
            if (!springDashpot)return false;
            //设置局部坐标系
        }
        return true;
    }

    bool FITKAbaqusAdaptorSpringDashpot::writeElementTwoPoints()
    {
        Interface::FITKAbaSpringDashpotPoint2Point* point2 = dynamic_cast<Interface::FITKAbaSpringDashpotPoint2Point*>(_dataObj);
        if (!point2 || !_writer || !_writeElementId || !_modelData)return false;
        QTextStream* stream = _writer->getStream();
        //获取节点对
        int count = point2->getDataCount();
        int modelId = _modelData->getDataObjectID();
        Interface::FITKAbaAssembly* assemblyData = dynamic_cast<Interface::FITKAbaAssembly*>(_modelData);
        //类型是否时指定方向 -是：type=Spring2/Dashpot2 否：type=SpringA/DashpotA
        QString name = point2->getDataObjectName();
        QString type = "A";
        if (point2->getStiffnessState())
        {
            QString springName = QString("%1-spring").arg(name);
            springName = springName.contains(' ') ? QString("\"%1\"").arg(springName) : springName;
            QString lineOne = QString("*Element, type=Spring%1, elset=%2").arg(type).arg(springName);
            *stream << lineOne << endl;
            for (int i = 0; i < count; ++i)
            {
                Interface::FITKAbaAssEleSpringDashpot* wireData = dynamic_cast<Interface::FITKAbaAssEleSpringDashpot*>(point2->getDataByIndex(i));
                if (!wireData)continue;
                int instanceId1, instanceId2, nodeId1, nodeId2;
                wireData->getNode1(instanceId1, nodeId1);
                wireData->getNode2(instanceId2, nodeId2);
                QString nodeText1 = QString::number(nodeId1);
                QString nodeText2 = QString::number(nodeId2);
                if (instanceId1 != modelId && assemblyData)
                {
                    Interface::FITKAbstractAssInstance* instanceData = assemblyData->getDataByID(instanceId1);
                    if (instanceData)
                    {
                        QString instanceName = instanceData->getDataObjectName();
                        instanceName = instanceName.contains(' ') ? QString("\"%1\"").arg(instanceName) : instanceName;
                        nodeText1 = QString("%1.%2").arg(instanceName).arg(nodeId1);
                    }  
                }
                if (instanceId2 != modelId && assemblyData)
                {
                    Interface::FITKAbstractAssInstance* instanceData = assemblyData->getDataByID(instanceId2);
                    if (instanceData)
                    {
                        QString instanceName = instanceData->getDataObjectName();
                        instanceName = instanceName.contains(' ') ? QString("\"%1\"").arg(instanceName) : instanceName;
                        nodeText2 = QString("%1.%2").arg(instanceName).arg(nodeId2);
                    }
                }
                *stream << QString("%1, %2, %3").arg(++(*_writeElementId)).arg(nodeText1).arg(nodeText2) << endl;
            }
        }
        if (point2->getDaspotState())
        {
            QString dashpotName = QString("%1-dashpot").arg(name);
            dashpotName = dashpotName.contains(' ') ? QString("\"%1\"").arg(dashpotName) : dashpotName;
            QString lineOne = QString("*Element, type=Dashpot%1, elset=%2").arg(type).arg(dashpotName);
            *stream << lineOne << endl;
            for (int i = 0; i < count; ++i)
            {
                Interface::FITKAbaAssEleSpringDashpot* wireData = dynamic_cast<Interface::FITKAbaAssEleSpringDashpot*>(point2->getDataByIndex(i));
                if (!wireData)continue;
                int instanceId1, instanceId2, nodeId1, nodeId2;
                wireData->getNode1(instanceId1, nodeId1);
                wireData->getNode2(instanceId2, nodeId2);
                QString nodeText1 = QString::number(nodeId1);
                QString nodeText2 = QString::number(nodeId2);
                if (instanceId1 != modelId && assemblyData)
                {
                    Interface::FITKAbstractAssInstance* instanceData = assemblyData->getDataByID(instanceId1);
                    if (instanceData)
                    {
                        QString instanceName = instanceData->getDataObjectName();
                        instanceName = instanceName.contains(' ') ? QString("\"%1\"").arg(instanceName) : instanceName;
                        nodeText1 = QString("%1.%2").arg(instanceName).arg(nodeId1);
                    }
                }
                if (instanceId2 != modelId && assemblyData)
                {
                    Interface::FITKAbstractAssInstance* instanceData = assemblyData->getDataByID(instanceId2);
                    if (instanceData)
                    {
                        QString instanceName = instanceData->getDataObjectName();
                        instanceName = instanceName.contains(' ') ? QString("\"%1\"").arg(instanceName) : instanceName;
                        nodeText2 = QString("%1.%2").arg(instanceName).arg(nodeId2);
                    }
                }
                *stream << QString("%1, %2, %3").arg(++(*_writeElementId)).arg(nodeText1).arg(nodeText2) << endl;
            }
        }
        return true;
    }
}